// Filename: registers.rs

// Importing necessary modules or libraries
// use std::ops::BitOr;
use core::ops::BitOr;
// ARMv8 AA64 REGISTERS

// SPSR_EL1 Register aarch64 (FROM ARM-ARM C5-395)
// Holds the saved process state when an exception is taken to EL1
#[derive(Debug, Copy, Clone)]
pub struct SPSR_EL1(u32);

impl SPSR_EL1 {
    pub const N: SPSR_EL1 = SPSR_EL1(1 << 31);
    pub const Z: SPSR_EL1 = SPSR_EL1(1 << 30);
    pub const C: SPSR_EL1 = SPSR_EL1(1 << 29);
    pub const V: SPSR_EL1 = SPSR_EL1(1 << 28);
    // Add other flags...

    pub const DIT: SPSR_EL1 = SPSR_EL1(1 << 24);
    pub const UAO: SPSR_EL1 = SPSR_EL1(1 << 23);
    pub const PAN: SPSR_EL1 = SPSR_EL1(1 << 22);
    pub const SS: SPSR_EL1 = SPSR_EL1(1 << 21);
    pub const IL: SPSR_EL1 = SPSR_EL1(1 << 20);
    pub const DEBUG: SPSR_EL1 = SPSR_EL1(1 << 9);
    pub const SERROR: SPSR_EL1 = SPSR_EL1(1 << 8);
    pub const IRQ: SPSR_EL1 = SPSR_EL1(1 << 7);
    pub const FIQ: SPSR_EL1 = SPSR_EL1(1 << 6);
    pub const M: SPSR_EL1 = SPSR_EL1(1 << 4);

    pub const EL0t: SPSR_EL1 = SPSR_EL1(0b0000);
    pub const EL1t: SPSR_EL1 = SPSR_EL1(0b0100);
    pub const EL1h: SPSR_EL1 = SPSR_EL1(0b0101);

    // SPSR_EL1 DEFAULT
    pub const KERNEL: SPSR_EL1 = SPSR_EL1::EL1h;
    pub const USER: SPSR_EL1 = SPSR_EL1::EL0t;
}

// SCTLR_EL1 System Control Register aarch64 (FROM ARM-ARM D12-3081)
#[derive(Debug, Copy, Clone)]
pub struct SCTLR_EL1(u32);

impl SCTLR_EL1 {
    pub const EnIA: SCTLR_EL1 = SCTLR_EL1(1 << 31);
    pub const EnIB: SCTLR_EL1 = SCTLR_EL1(1 << 30);
    // Add other flags...

    pub const EnDA: SCTLR_EL1 = SCTLR_EL1(1 << 27);
    pub const UCI: SCTLR_EL1 = SCTLR_EL1(1 << 26);
    pub const EE: SCTLR_EL1 = SCTLR_EL1(1 << 25);
    pub const E0E: SCTLR_EL1 = SCTLR_EL1(1 << 24);
    // Add other flags...

    pub const UMA: SCTLR_EL1 = SCTLR_EL1(1 << 9);
    pub const SED: SCTLR_EL1 = SCTLR_EL1(1 << 8);
    // Add other flags...

    pub const CP15BEN: SCTLR_EL1 = SCTLR_EL1(1 << 5);
    pub const SA0: SCTLR_EL1 = SCTLR_EL1(1 << 4);
    // Add other flags...

    // SCTLR_EL1_M is represented by the MMU enable flag
    pub const M: SCTLR_EL1 = SCTLR_EL1(1 << 0);
}

// Types of the registers
#[derive(Debug, Copy, Clone)]
pub enum Register {
    X0,
    X1,
    // Add other registers...
    SP_EL0,
    ELR_EL1,
    SPSR_EL1,
    TPIDR_EL0,
}

pub const REG_NUM: usize = 35;
pub const SZ_U64: usize = 8;
pub const ARCH_EXEC_CONT_SIZE: usize = REG_NUM * SZ_U64;
/*
fn main() {
    // Example usage
    let spsr_kernel = SPSR_EL1::KERNEL;
    let sctlr_enia = SCTLR_EL1::EnIA;
    let register_x0 = Register::X0;

    println!("{:?}", spsr_kernel);
    println!("{:?}", sctlr_enia);
    println!("{:?}", register_x0);
}
*/
